#ifndef _FF_H_
#define _FF_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <windows.h>
#include <io.h>

#define FF_CODE_PAGE	0

extern WORD CodePage;

typedef struct {
    HANDLE handle;
} FIL;

#define FF_USE_LFN      1
#define FF_LFN_UNICODE  2
#define FF_MAX_LFN		255
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ             0x01
#define FA_WRITE            0x02
#define FA_OPEN_EXISTING    0x00
#define FA_CREATE_NEW       0x04
#define FA_CREATE_ALWAYS    0x08
#define FA_OPEN_ALWAYS      0x10
#define FA_OPEN_APPEND      0x30

typedef unsigned long long FSIZE_t;
typedef unsigned int       uint32_t;
typedef enum {
    FR_OK = 0,              /* (0) Succeeded */
    FR_DISK_ERR,            /* (1) A hard error occurred in the low level disk I/O layer */
    FR_INT_ERR,             /* (2) Assertion failed */
    FR_NOT_READY,           /* (3) The physical drive cannot work */
    FR_NO_FILE,             /* (4) Could not find the file */
    FR_NO_PATH,             /* (5) Could not find the path */
    FR_INVALID_NAME,        /* (6) The path name format is invalid */
    FR_DENIED,              /* (7) Access denied due to prohibited access or directory full */
    FR_EXIST,               /* (8) Access denied due to prohibited access */
    FR_INVALID_OBJECT,      /* (9) The file/directory object is invalid */
    FR_WRITE_PROTECTED,     /* (10) The physical drive is write protected */
    FR_INVALID_DRIVE,       /* (11) The logical drive number is invalid */
    FR_NOT_ENABLED,         /* (12) The volume has no work area */
    FR_NO_FILESYSTEM,       /* (13) There is no valid FAT volume */
    FR_MKFS_ABORTED,        /* (14) The f_mkfs() aborted due to any problem */
    FR_TIMEOUT,             /* (15) Could not get a grant to access the volume within defined period */
    FR_LOCKED,              /* (16) The operation is rejected according to the file sharing policy */
    FR_NOT_ENOUGH_CORE,     /* (17) LFN working buffer could not be allocated */
    FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
    FR_INVALID_PARAMETER    /* (19) Given parameter is invalid */
} FRESULT;


typedef struct {
    BYTE    fs_type;        /* Filesystem type (0:N/A) */
    BYTE    pdrv;           /* Physical drive number */
    BYTE    n_fats;         /* Number of FATs (1 or 2) */
    BYTE    wflag;          /* win[] flag (b0:dirty) */
    BYTE    fsi_flag;       /* FSINFO flags (b7:disabled, b0:dirty) */
    WORD    id;             /* Volume mount ID */
    WORD    n_rootdir;      /* Number of root directory entries (FAT12/16) */
    DWORD   csize;          /* Cluster size [sectors], must be 32bits */
} FATFS;


/* Directory object structure (DIR) */

typedef struct {
	HANDLE hFind;
	WIN32_FIND_DATA FindData;
} DIR;


/* File information structure (FILINFO) */

typedef struct {
    FSIZE_t fsize;          /* File size */
    WORD    fdate;          /* Modified date */
    WORD    ftime;          /* Modified time */
    BYTE    fattrib;        /* File attribute */
#if FF_USE_LFN
    TCHAR   altname[13];            /* Altenative file name */
    TCHAR   fname[FF_MAX_LFN + 1];  /* Primary file name */
#else
    char   fname[MAXPATH];      /* File name */
#endif
} FILINFO;

/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO  0x01    /* Read only */
#define AM_HID  0x02    /* Hidden */
#define AM_SYS  0x04    /* System */
#define AM_DIR  0x10    /* Directory */
#define AM_ARC  0x20    /* Archive */

FRESULT f_open (FIL* fp, const char* path, unsigned char mode);             /* Open or create a file */
FRESULT f_close (FIL* fp);                                          /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, unsigned int btr, unsigned int* br);           /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, unsigned int btw, unsigned int* bw);    /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs);                             /* Move file pointer of the file object */
FSIZE_t f_size(FIL* fp);
FSIZE_t f_tell(FIL* fp);
char* f_gets (char* buff, int len, FIL* fp);                      /* Get a string from the file */
FRESULT f_stat (const char* path, FILINFO* fno); 
FRESULT f_mkdir (const char* path); 
FRESULT f_unlink (const char* path);                               /* Delete an existing file or directory */
FRESULT f_rename (const char* path_old, const char* path_new);    /* Rename/Move a file or directory */
FRESULT f_opendir (DIR* dp, const char* path);                     /* Open a directory */
FRESULT f_closedir (DIR* dp);                                       /* Close an open directory */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const char* path, const char* pattern);   /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno);                         /* Find next file */
FRESULT f_truncate (FIL* fp);										/* Truncate the file */
FRESULT f_sync (FIL* fp);                                           /* Flush cached data of the writing file */
FRESULT f_getfree (const char* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
unsigned int ext_getfree(unsigned char flag);
FRESULT sdmmc_disk_check(int dev);
FRESULT ext_delete_tree(char* path);
uint32_t ext_get_free_(DWORD* nclst, DWORD* clust_size);
//#define f_eof(fp)	((int)((fp)->fptr == (fp)->obj.objsize))
#define f_eof(fp)	((int)(f_size((fp)) == f_tell((fp)))
//#define f_error(fp) ((fp)->err)

#ifdef __cplusplus
}
#endif

#endif /* _PCM_H_ */
